package com.wwdx.controller.base;

import com.wwdx.model.WwdxOpenAuthModel;
import com.wwdx.model.dto.ResultBean;
import com.wwdx.service.impl.BaseWxOpenService;
import com.wwdx.utils.ConstantHolder;
import com.wwdx.utils.QrCodeUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.open.api.WxOpenComponentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;

/**
 * @author liguoliang
 * @date 2018/9/30 18:40
 */
public abstract class BaseMerchantController extends BaseController{

    /**
     * 获取子类service
     * @return BaseWxOpenService
     */
    protected abstract BaseWxOpenService getWxOpenService();

    /**
     * 分销商推广链接(未绑定)
     * @param redirectURI 授权后跳转地址
     */
    @RequestMapping("/extensionlink/unauthorized")
    @ApiOperation(value = "分销商推广链接",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "令牌",required = true),
            @ApiImplicitParam(name = "sign",value = "签名",required = true),
            @ApiImplicitParam(name = "timestamp",value = "时间戳",required = true),
            @ApiImplicitParam(name = "redirectURI",value = "授权后跳转地址",required = true)
    })
    public ResultBean extensionlinkUnauthorized(String token, String sign, String timestamp, String redirectURI) {
        ResultBean resultBean = this.validSignTokenResult(sign,super.getSortedMap(token, timestamp));
        if (resultBean.getStatus() == 1){
            return resultBean;
        }
        String openId = (String) resultBean.getData();
        try {
            Map<String,Object> map;
            String key = String.format(ConstantHolder.MERCHANT_SHORTURL_MAP, openId);
            Boolean exists = redisTemplate.execute((RedisConnection connection) -> connection.exists(key.getBytes()));
            if (exists){
                map = hashOperations.entries(key);
            }else {
                map = new HashMap<>(2);
                String url = merchantWxService.shortUrl(merchantWxService.oauth2buildAuthorizationUrl(redirectURI, WxConsts.OAuth2Scope.SNSAPI_USERINFO, null));
                map.put("shortUrl",url);
                hashOperations.putAll(key,map);
                redisTemplate.expire(key, 24 * 60 * 60, TimeUnit.SECONDS);
            }
            return renderSuccess(map);
        }catch (WxErrorException e){
            logger.error(e.getMessage());
            return renderError(e.getMessage());
        }
    }

    /**
     * 分销商推广链接及二维码(绑定)
     * @param redirectURI 授权后跳转地址
     */
    @RequestMapping("/extensionlink/authorized")
    @ApiOperation(value = "分销商推广链接",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "令牌",required = true),
            @ApiImplicitParam(name = "sign",value = "签名",required = true),
            @ApiImplicitParam(name = "timestamp",value = "时间戳",required = true),
            @ApiImplicitParam(name = "redirectURI",value = "授权后跳转地址",required = true)
    })
    public ResultBean extensionlink(String token, String sign, String timestamp, String redirectURI) {
        ResultBean resultBean = this.validSignTokenAndMerchantResult(sign,super.getSortedMap(token, timestamp));
        if (resultBean.getStatus() == 1){
            return resultBean;
        }
        String authorizerAppid = (String) resultBean.getData();
        try {
            Map<String,Object> map;
            String key = String.format(ConstantHolder.MERCHANT_SHORTURL_MAP, authorizerAppid);
            Boolean exists = redisTemplate.execute((RedisConnection connection) -> connection.exists(key.getBytes()));
            if (exists){
                map = hashOperations.entries(key);
            }else {
                WxOpenComponentService wxOpenComponentService = this.getWxOpenService().getWxOpenComponentService();
                String url = wxOpenComponentService
                        .oauth2buildAuthorizationUrl(authorizerAppid, redirectURI, WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
                WxMpService wxMpService = wxOpenComponentService.getWxMpServiceByAppid(authorizerAppid);
                map = new HashMap<>(2);
                map.put("shortUrl",wxMpService.shortUrl(url));
                hashOperations.putAll(key,map);
                redisTemplate.expire(key, 24 * 60 * 60, TimeUnit.SECONDS);
            }
            return renderSuccess(map);
        }catch (WxErrorException e){
            logger.error(e.getMessage());
            return renderError(e.getMessage());
        }
    }

    /**
     * 分销商推广链接二维码
     */
    @RequestMapping("/qrcode")
    @ApiOperation(value = "获取二维码图片",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "令牌"),
            @ApiImplicitParam(name = "sign",value = "签名"),
            @ApiImplicitParam(name = "timestamp",value = "时间戳"),
            @ApiImplicitParam(name = "redirectURI",value = "授权后跳转地址",required = true)
    })
    public void qrcode(String token, String sign, String timestamp, String redirectURI, HttpServletResponse response)throws Exception {
        //未绑定
        if (StringUtils.isBlank(token) && StringUtils.isBlank(sign) && StringUtils.isBlank(timestamp)){
            String orginal = wechatUrl+"auth.html?url="+ URIUtil.encodeURIComponent(redirectURI);
            QrCodeUtil.encode(merchantWxService.shortUrl(orginal),response.getOutputStream());
            return;
        }
        //绑定
        ResultBean resultBean = this.validSignTokenAndMerchantResult(sign,super.getSortedMap(token, timestamp));
        if (resultBean.getStatus() == 1){
            return;
        }
        String authorizerAppid = (String) resultBean.getData();
        WxOpenComponentService wxOpenComponentService = this.getWxOpenService().getWxOpenComponentService();
        WxMpService wxMpService = wxOpenComponentService.getWxMpServiceByAppid(authorizerAppid);
        String url = wxOpenComponentService
                .oauth2buildAuthorizationUrl(authorizerAppid, redirectURI, WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
        String shortUrl = wxMpService.shortUrl(url);
        QrCodeUtil.encode(shortUrl,response.getOutputStream());
    }

    /**
     * 获取商户模版
     */
    @RequestMapping("/template/get")
    @ApiOperation(value = "获取商户模版",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token",value = "令牌",required = true),
            @ApiImplicitParam(name = "sign",value = "签名",required = true),
            @ApiImplicitParam(name = "timestamp",value = "时间戳",required = true)
    })
    public ResultBean templateGet(String token,String sign, String timestamp){
        ResultBean resultBean = this.validSignTokenAndMerchantResult(sign,super.getSortedMap(token, timestamp));
        if (resultBean.getStatus() == 1){
            return resultBean;
        }
        String authorizerAppid = (String) resultBean.getData();
        try {
            WxOpenComponentService wxOpenComponentService = this.getWxOpenService().getWxOpenComponentService();
            WxMpService wxMpService = wxOpenComponentService.getWxMpServiceByAppid(authorizerAppid);
            return renderSuccess(wxMpService.getTemplateMsgService().getAllPrivateTemplate());
        }catch (WxErrorException e){
            logger.error(e.getMessage());
            return renderError(e.getMessage());
        }
    }

    /**
     * 验证用户登录及商户存在状态
     */
    private ResultBean validSignTokenAndMerchantResult(String sign, SortedMap<String, Object> sortedMap){
        ResultBean resultBean = super.validSignTokenResult(sign,sortedMap);
        if (resultBean.getStatus() == 1){
            return resultBean;
        }
        String openId = (String) resultBean.getData();
        WwdxOpenAuthModel wwdxOpenAuthModel = wwdxOpenAuthService.getByOpenIdAndStatus(openId, ConstantHolder.Constant.AUTHORIZED);
        if (wwdxOpenAuthModel == null){
            return renderError("商户不存在");
        }
        resultBean.setData(wwdxOpenAuthModel.getAuthorizerAppid());
        return resultBean;
    }
}